package blue.base.internal.core.path;

import blue.base.core.path.FilePath;
import blue.base.core.util.AssertUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author Jin Zheng
 * @since 1.0 2021-02-19
 */
public class DefaultFilePath implements FilePath {

	private final String originalPath;
	private final List<String> pathList;

	public DefaultFilePath(String path) {
		AssertUtil.notEmpty(path, "Original Path");
		this.originalPath = path;
		this.pathList = this.parse(path);
	}

	private DefaultFilePath(String originalPath, List<String> pathList) {
		this.originalPath = originalPath;
		this.pathList = new ArrayList<>(pathList);
	}

	private List<String> parse(String path) {
		List<String> pathList = new ArrayList<>();
		String[] paths = path.split(SLASH);
		for (var p : paths) {
			if (p == null || p.isEmpty())
				continue;

			pathList.add(p);
		}
		return pathList;
	}

	@Override
	public String getOriginalPath() {
		return originalPath;
	}

	@Override
	public String getCurrentPath() {
		StringBuilder sb = new StringBuilder(SIZE);
		for (var path : pathList) {
			sb.append(SLASH).append(path);
		}
		return sb.toString();
	}

	@Override
	public String concat(Object... paths) {
		if (paths.length == 0) {
			return this.getCurrentPath();
		}

		for (Object path : paths) {
			var tmp = this.parse(path.toString());
			pathList.addAll(tmp);
		}
		return this.getCurrentPath();
	}

	@Override
	public String concat(Collection<?> paths) {
		if (paths == null || paths.isEmpty()) {
			return this.getCurrentPath();
		}

		for (Object path : paths) {
			var tmp = this.parse(path.toString());
			pathList.addAll(tmp);
		}
		return this.getCurrentPath();
	}

	@Override
	public String subPath(String path) {
		if (path == null || path.isEmpty() || SLASH.equals(path)) {
			return this.getCurrentPath();
		}
		var tmp = this.parse(path);
		if (tmp.isEmpty() || tmp.size() > pathList.size()) {
			return this.getCurrentPath();
		}

		boolean match = true;
		for (int i = 0; i < tmp.size(); i++) {
			if (!tmp.get(i).equals(pathList.get(i))) {
				match = false;
				break;
			}
		}
		if (match) {
			pathList.removeAll(tmp);
		}
		return this.getCurrentPath();
	}

	@Override
	public FilePath copy() {
		return new DefaultFilePath(this.originalPath, this.pathList);
	}
}
